home *** CD-ROM | disk | FTP | other *** search
- UNIT Sort;
-
- { These sort routines are for arrays of Integers. Count is the maximum }
- { number of items in the array. }
-
- {****************************************************************************}
- INTERFACE
- {****************************************************************************}
- FUNCTION BinarySearch (VAR A; X : Integer; Count : Integer) : Integer;
- PROCEDURE BubbleSort (VAR A; Count : Integer); {slow}
- PROCEDURE CombSort (VAR A; Count : Integer);
- PROCEDURE QuickSort (VAR A; Count : Integer); {fast}
- FUNCTION SequentialSearch (VAR A; X : Integer; Count : Integer) : Integer;
- PROCEDURE ShellSort (VAR A; Count : Integer); {moderate}
- {****************************************************************************}
- IMPLEMENTATION
- {****************************************************************************}
- TYPE
- SortArray = ARRAY[0..0] OF Integer;
- {****************************************************************************}
- { }
- { Local Procedures and Functions }
- { }
- {****************************************************************************}
- PROCEDURE Swap (VAR A, B : Integer);
- VAR C : Integer;
- BEGIN
- C := A;
- A := B;
- B := C;
- END;
- {****************************************************************************}
- { }
- { Global Procedures and Functions }
- { }
- {****************************************************************************}
- FUNCTION BinarySearch (VAR A; X : Integer; Count : Integer) : Integer;
- VAR High, Low, Mid : Integer;
- BEGIN
- Low := 1;
- High := Count;
- WHILE High >= Low DO
- BEGIN
- Mid := Trunc(High + Low) DIV 2;
- IF X > SortArray(A)[mid]
- THEN Low := Mid + 1
- ELSE IF X < SortArray(A)[Mid]
- THEN High := Mid - 1
- ELSE High := -1;
- END;
- IF High = -1
- THEN BinarySearch := Mid
- ELSE BinarySearch := 0;
- END;
- {****************************************************************************}
- PROCEDURE BubbleSort (VAR A; Count : Integer);
- VAR i, j : Integer;
- BEGIN
- FOR i := 2 TO Count DO
- FOR j := Count DOWNTO i DO
- IF SortArray(A)[j-1] > SortArray(A)[j]
- THEN Swap(SortArray(A)[j],SortArray(A)[j-1]);
- END;
- {****************************************************************************}
- PROCEDURE CombSort (VAR A; Count : Integer);
- { The combsort is an optimised version of the bubble sort. It uses a }
- { decreasing gap in order to compare values of more than one element }
- { apart. By decreasing the gap the array is gradually "combed" into }
- { order ... like combing your hair. First you get rid of the large }
- { tangles, then the smaller ones ... }
- { There are a few particular things about the combsort. }
- { Firstly, the optimal shrink factor is 1.3 (worked out through a }
- { process of exhaustion by the guys at BYTE magazine). Secondly, by }
- { never having a gap of 9 or 10, but always using 11, the sort is }
- { faster. }
- { This sort approximates an n log n sort - it's faster than any other }
- { sort I've seen except the quicksort (and it beats that too sometimes). }
- { The combsort does not slow down under *any* circumstances. In fact, on }
- { partially sorted lists (including *reverse* sorted lists) it speeds up.}
- CONST ShrinkFactor = 1.3; { Optimal shrink factor ... }
- VAR
- Gap, i, Temp : Integer;
- Finished : Boolean;
- BEGIN
- Gap := Trunc(ShrinkFactor);
- REPEAT
- Finished := TRUE;
- Gap := Trunc(Gap/ShrinkFactor);
- IF Gap < 1
- THEN { Gap must *never* be less than 1 } Gap := 1
- ELSE IF Gap IN [9,10]
- THEN { Optimises the sort ... } Gap := 11;
- FOR i := 1 TO (Count - Gap) DO
- IF SortArray(A)[i] < SortArray(A)[i+gap]
- THEN BEGIN
- Swap(SortArray(A)[i],SortArray(A)[i + Gap]);
- Finished := FALSE;
- END;
- UNTIL (Gap = 1) AND Finished;
- END;
- {****************************************************************************}
- PROCEDURE QuickSort (VAR A; Count : Integer);
- {**************************************************************************}
- PROCEDURE PartialSort(LowerBoundary, UpperBoundary : Integer; VAR A);
- VAR ii, l1, r1, i, j, k : Integer;
- BEGIN
- k := (SortArray(A)[LowerBoundary] + SortArray(A)[UpperBoundary]) DIV 2;
- i := LowerBoundary;
- j := UpperBoundary;
- REPEAT
- WHILE SortArray(A)[i] < k DO Inc(i);
- WHILE k < SortArray(A)[j] DO Dec(j);
- IF i <= j
- THEN BEGIN
- Swap(SortArray(A)[i],SortArray(A)[j]);
- Inc(i);
- Dec(j);
- END;
- UNTIL i > j;
- IF LowerBoundary < j
- THEN PartialSort(LowerBoundary,j,A);
- IF i < UpperBoundary
- THEN PartialSort(UpperBoundary,i,A);
- END;
- {*************************************************************************}
- BEGIN
- PartialSort(1,Count,A);
- END;
- {****************************************************************************}
- FUNCTION SequentialSearch (VAR A; X : Integer; Count : Integer) : Integer;
- VAR i : Integer;
- BEGIN
- FOR i := 1 TO Count DO
- IF X = Sortarray(A)[i]
- THEN BEGIN
- SequentialSearch := i;
- Exit;
- END;
- SequentialSearch := 0;
- END;
- {****************************************************************************}
- PROCEDURE ShellSort (VAR A; Count : Integer);
- VAR Gap, i, j, k : Integer;
- BEGIN
- Gap := Count DIV 2;
- WHILE (gap > 0) DO
- BEGIN
- FOR i := (Gap + 1) TO Count DO
- BEGIN
- j := i - Gap;
- WHILE (j > 0) DO
- BEGIN
- k := j + gap;
- IF (SortArray(A)[j] <= SortArray(A)[k])
- THEN j := 0
- ELSE Swap(SortArray(A)[j],SortArray(A)[k]);
- j := j - Gap;
- END;
- END;
- Gap := Gap DIV 2;
- END;
- END;
- {*****************************************************************************}
- END.